<?php defined('SYSPATH') OR die('No direct script access.');

class Response extends Kohana_Response {

	public static $initial;

	public static function factory(array $config = array())
	{
		if ( ! Response::$initial)
			return Response::$initial = new Response($config);
		else
			return new Response($config);
	}

	public function is_initial()
	{
		return ($this === Response::$initial);
	}

	public static function initial()
	{
		return Response::$initial;
	}

	/**
	 * Send a file using the X-Sendfile header. The server must support this
	 * header in order to send the file.
	 *
	 * [!!] Unlike Response::send_file, this method _does not_ stop execution
	 *      and more processing may be done. However, the body will be discarded
	 *      because the X-Sendfile header is being used
	 *
	 * @param  string  $file_path  The absolute path to the file to be sent
	 * @param  string  $down_filename  Override the file name
	 * @param  boolean $inline     Display the file instead of downloading it
	 */

	public function x_send_file($file_path, $down_filename = NULL, array $options = NULL)
	{
		if ( ! file_exists($file_path))
			throw new Kohana_Exception("Attempted to send missing file, [:file_path]", array(
				':file_path' => $file_path,
			));
 		@ob_clean(); //在输出文件前,清除缓冲区

		if (!empty($down_filename))
		{
			empty($options['mime_type']) && $options['mime_type'] = File::mime($down_filename);
			$ua = $_SERVER["HTTP_USER_AGENT"];
			if (preg_match("/MSIE/", $ua)) {
				$down_filename = urlencode($down_filename);
				$down_filename = str_replace("+", "%20", $down_filename);
			}
			// Get the content disposition
			$disposition = empty($options['inline']) ? 'attachment' : 'inline';
			$this->headers('Content-Disposition', $disposition.'; filename="'.$down_filename.'"');
		}
 		!isset($options['resumable']) && $options['resumable'] = TRUE; //默认支持断点传输
 		empty($options['mime_type']) && $options['mime_type'] = File::mime($file_path);
		!empty($options['mime_type']) && $this->headers('Content-Type', $options['mime_type']);
		$this->headers('Last-Modified', date('r', empty($options['last_modified']) ? filemtime($file_path) : $options['last_modified']));
		$this->headers('Etag', $options['etag'] = '"'.(empty($options['etag']) ? md5(serialize(fileinfo($file_path))) : $options['etag']).'"');
		$this->headers('Content-Length', empty($options['content_length']) ? filesize($file_path) : $options['content_length']);
		if (!empty($_SERVER['HTTP_IF_NONE_MATCH']) && trim($_SERVER['HTTP_IF_NONE_MATCH']) == $options['etag'])
		{
			$this->status(304);
			$this->send_headers();
			return;
		}


 		switch (substr($_SERVER['SERVER_SOFTWARE'], 0, (int)strpos($_SERVER['SERVER_SOFTWARE'],'/'))) {
			case 'nginx':
				$this->headers('X-Accel-Redirect', URL::site(relative_path($file_path, APPPATH), NULL, FALSE));
				$this->headers('X-Accel-Buffering', 'yes');
				//$this->headers('X-Accel-Limit-Rate', '102400'); //速度限制 Byte/s
				//$this->headersheader('Accept-Ranges', 'none');//单线程 限制多线程
				break;
			case 'Apache':
				if (function_exists('apache_get_modules') && in_array('mod_xsendfile', apache_get_modules()))
				{
					$this->headers('X-Sendfile', $file_path);
				}
				else
				{
					if (!empty($down_filename)) //是下载，则调取系统默认的下载函数
						$this->send_file($file_path, $down_filename, $options);
					else
						readfile($file_path);
				}
				break;
			case 'squid':
				$this->headers('X-Accelerator-Vary', $file_path);
				break;
			case 'lighttpd':
				$this-->headers('X-LIGHTTPD-send-file', $file_path);
				break;
			default:
				if (!empty($down_filename)) //是下载，则调取系统默认的下载函数
					$this->send_file($file_path, $down_filename, $options);
				else
					readfile($file_path);
				break;
		}
		$this->send_headers();
	}
 
}
